package services

import (
	"gitee.com/igolang/imoney/internal/app/system/entities"
	"gitee.com/igolang/imoney/internal/app/system/tools"
	commonEntities "gitee.com/igolang/imoney/internal/common/entities"
	"gitee.com/igolang/imoney/internal/common/httpResp"
	commonTools "gitee.com/igolang/imoney/internal/common/tools"
	"gitee.com/igolang/imoney/internal/models/dao"
	"gitee.com/igolang/imoney/internal/models/model"
	"gitee.com/igolang/pkg/xgorm"
	"gitee.com/igolang/pkg/xtime"
	"github.com/gin-gonic/gin"
	"github.com/spf13/cast"
	"gorm.io/gen"
	"time"
)

var Notice = &notice{}

type notice struct{}

func (s *notice) List(ctx *gin.Context) (*commonEntities.ListResp, error) {
	var req entities.NoticePageListReq
	if err := ctx.ShouldBind(&req); err != nil {
		return nil, err
	}
	req.Page()
	conds := s.formatListConds(req)
	total, err := dao.SysNotice.Where(conds...).Count()
	if err != nil {
		return nil, err
	}
	result := &commonEntities.ListResp{
		Total: total,
		Rows:  make([]*model.SysNotice, 0),
	}
	if total == 0 {
		return result, nil
	}
	result.Rows, err = dao.SysNotice.Omit(dao.SysNotice.NoticeContent).Where(conds...).Offset(req.Offset).Limit(req.PageSize).Order(dao.SysNotice.NoticeID.Desc()).Find()
	return result, err
}

func (s *notice) Save(ctx *gin.Context) (err error) {
	var req map[string]any
	if err = ctx.ShouldBindJSON(&req); err != nil {
		return err
	}

	row := &model.SysNotice{
		NoticeID:      cast.ToInt64(req["noticeId"]),
		NoticeTitle:   cast.ToString(req["noticeTitle"]),
		NoticeType:    cast.ToString(req["noticeType"]),
		NoticeContent: []byte(cast.ToString(req["noticeContent"])),
		Status:        cast.ToString(req["status"]),
		Remark:        cast.ToString(req["remark"]),
	}

	if row.NoticeTitle == "" || row.NoticeType == "" || len(row.NoticeContent) == 0 {
		return httpResp.ErrorCode(httpResp.ErrCodeInvalidParams)
	}
	if row.Status == "" {
		row.Status = "0"
	}
	userInfo := tools.GetUserInfo(ctx)
	row.UpdateTime = xtime.Time(time.Now())
	row.UpdateBy = userInfo.User.UserName
	if row.NoticeID == 0 {
		row.CreateTime = xtime.Time(time.Now())
		row.CreateBy = userInfo.User.UserName
		return dao.SysNotice.Create(row)
	}
	rawRow, err := dao.SysNotice.Where(dao.SysNotice.NoticeID.Eq(row.NoticeID)).Take()
	if err != nil {
		return err
	}
	rawRow.Status = row.Status
	rawRow.NoticeTitle = row.NoticeTitle
	rawRow.NoticeContent = row.NoticeContent
	rawRow.NoticeType = row.NoticeType
	rawRow.UpdateTime = row.UpdateTime
	rawRow.UpdateBy = row.UpdateBy
	data := xgorm.ModelToMap(rawRow)
	_, err = dao.SysNotice.Where(dao.SysNotice.NoticeID.Eq(row.NoticeID)).Updates(data)
	return
}

func (s *notice) Delete(ctx *gin.Context) error {
	ids := commonTools.String2Int64s(ctx.Param("ids"))
	if len(ids) == 0 {
		return httpResp.ErrorCode(httpResp.ErrCodeInvalidParams)
	}
	_, err := dao.SysNotice.Where(dao.SysNotice.NoticeID.In(ids...)).Delete()
	return err
}

func (s *notice) formatListConds(req entities.NoticePageListReq) []gen.Condition {
	conds := make([]gen.Condition, 0)
	if req.NoticeTitle != "" {
		conds = append(conds, dao.SysNotice.NoticeTitle.Like(`%`+req.NoticeTitle+`%`))
	}
	if req.NoticeType != "" {
		conds = append(conds, dao.SysNotice.NoticeType.Eq(req.NoticeType))
	}

	if req.CreateBy != "" {
		conds = append(conds, dao.SysNotice.CreateBy.Eq(req.CreateBy))
	}

	return conds
}
